package com.gxa.realm;
import com.gxa.mapper.RoleMapper;
import com.gxa.pojo.Employee;
import com.gxa.pojo.PowerMenu;
import com.gxa.pojo.Role;
import com.gxa.service.EmployeeService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * Created with IntelliJ IDEA.
 * User: zdk
 * Date: 2020/10/24 9:44
 * Description: 自定义的realm
 * Version: V1.0
 */
@Component
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private EmployeeService employeeService;

    @Autowired(required = false)
    private RoleMapper roleMapper;

    /**
     *  授权的方法
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("==============================");
        //1、获取用户名
        String employeeUsername = (String) principalCollection.getPrimaryPrincipal();
        //2、获取用户对象
        Employee employee =  employeeService.findByEmployeeUsername(employeeUsername);
        //3、根据用户对象查找对应的角色
        List<Role> rolesList = roleMapper.findRoleByEmployee(employee.getEmployeeId());
        Set<String> roles = getRolesByEmployee(rolesList);
        //4、获取权限数据
        Set<String> permissions = getPermissionByRole(rolesList);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //设置角色和权限数据
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }

    /**
     * 认证的方法
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户名
        String employeeUsername = (String) authenticationToken.getPrincipal();
        //通过用户名获取密码
        String employeePwd = getPwdByUserName(employeeUsername);
        if(employeePwd != null){
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(employeeUsername,employeePwd,"myRealm");
            //加盐
            info.setCredentialsSalt(ByteSource.Util.bytes("jiami"));
            return info;
        }
        return null;
    }

    /**
     * 根据用户名查询密码
     * @param employeeUsername
     * @return
     */
    private String getPwdByUserName(String employeeUsername) {
        //调用Service查询
        Employee employee = employeeService.findByEmployeeUsername(employeeUsername);
        if(employee != null){
            return employee.getEmployeePwd();
        }
        return null;
    }
    /**
     * 根据角色查找对应的权限
     * @param roles
     * @return
     */
    private Set<String> getPermissionByRole(List<Role> roles) {
        if (roles.isEmpty() || roles == null){
            return null;
        }
        Set<String> sets = new HashSet<>();
        List<Integer> listRoleId = new ArrayList<>();
        for (Role role :roles) {
            listRoleId.add(role.getRoleId());
        }
        List<PowerMenu> powerMenuList = roleMapper.findPowerMenuByRoleId(listRoleId);
        if (powerMenuList == null || powerMenuList.isEmpty()){
            return null;
        }
        for (PowerMenu powerMenu : powerMenuList) {
            sets.add(powerMenu.getPowerMenuName());
        }
        return sets;
    }
    /**
     * 根据用户查找对应的角色
     * @param rolesList
     * @return
     */
    private Set<String> getRolesByEmployee(List<Role> rolesList) {
        if(rolesList != null || !rolesList.isEmpty()){
            Set<String> setRoles = new HashSet<>();
            for (Role role:rolesList) {
                setRoles.add(role.getRoleName());
            }
            return setRoles;
        }
        return null;
    }
}
